// 自定义工具函数
import { ColumnProps, UserProps, ImageProps } from "./store";
import createMessage from "./components/createMessage";
// 组合生成 头像路径
export function generateFitUrl(
  data: ImageProps,
  width: number,
  height: number,
  format = ["m_pad"]
) {
  if (data && data.url) {
    const formatStr = format.reduce((prev, current) => {
      return current + "," + prev;
    }, "");
    // 阿里云图片资源 可以缩放
    data.fitUrl =
      data.url +
      `?x-oss-process=image/resize,${formatStr}h_${height},w_${width}`;
  }
}

// 专栏图 or 用户头像 通用的addColumnAvatar
export function addColumnAvatar(
  data: ColumnProps | UserProps,
  width: number,
  height: number
) {
  if (data.avatar) {
    generateFitUrl(data.avatar, width, height);
  } else {
    const parseCol = data as ColumnProps;
    // 此时没有头像的话就要用assets文件夹下的头像
    // 这里的 require 是 webpack 帮我们处理的静态资源 vue-cli 运行打包的过程底层是 webpack，
    // 有了 webpack，我们可以使用 import 或者 require 这类语句引入不同的模块
    // console.log(data, parseCol);
    data.avatar = {
      fitUrl: require(parseCol.title
        ? "@/assets/column.jpg"
        : "@/assets/avatar.jpg")
    };
  }
}
// 检查文件上传时候的file类型 大小等要求
interface CheckCondition {
  format?: string[];
  size?: number;
} //兆为单位
// 报错信息类型
type ErrorType = "format" | "size" | null;
export function beforeUploadCheck(file: File, condition: CheckCondition) {
  const { format, size } = condition;
  const isValidFormat = format ? format.includes(file.type) : true;
  const isValidSize = size ? file.size / 1024 / 1024 < size : true;
  let error: ErrorType = null;
  if (!isValidFormat) {
    error = "format";
  }
  if (!isValidSize) {
    error = "size";
  }
  return {
    passed: isValidFormat && isValidSize,
    error
  };
}

export const commonUploadCheck = (file: File) => {
  const result = beforeUploadCheck(file, {
    format: ["image/jpeg", "image/png"],
    size: 1
  });
  const { passed, error } = result;
  if (error === "format") {
    createMessage("上传图片只能是 JPG/PNG 格式!", "error", 2000, "关闭");
  }
  if (error === "size") {
    createMessage("上传图片大小不能超过 1Mb", "error", 2000, "关闭");
  }
  return passed;
};
// 测试数据
// 传入的数据格式 例如 testData
interface TestProps {
  _id: string;
  name: string;
}
const testData: TestProps[] = [
  { _id: "1", name: "a" },
  { _id: "2", name: "b" }
];

export const arrToObj = <T extends { _id?: string }>(arr: Array<T>) => {
  // 1. 参数arr是使用的时候再来确定其类型格式，设置泛型对应TestProps属性
  // 2.约束泛型 <T extends { _id?: string }> 规定T 泛型中是含有_id属性的对象类型
  return arr.reduce((prev, current) => {
    if (current._id) {
      // 把当前值的_id拿出来
      prev[current._id] = current; // 赋给prev的key
    }
    return prev; // 返回prev
  }, {} as { [key: string]: T }); //3.类型断言 初始值需要断言成testData2的格式 里面用到了ts中的“可索引的类型”概念，通过xxx[key]查找时，规定key为string类型，查找到的value为T（输入的数组）类型
};
const result = arrToObj(testData);
// console.log(result);
// 输出格式：Object
// 1: {_id: '1', name: 'a'}
// 2: {_id: '2', name: 'b'}
// [[Prototype]]: Object

// Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组，数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
// 这里 Object.keys(obj) ==> ['1','2'] map方法返回一个数组,里面是输入对象对应的value值
export const objToArr = <T>(obj: { [key: string]: T }) => {
  return Object.keys(obj).map(key => obj[key]);
};

// 需要输出的数据格式 例如testData2 是一种具有键值对的形式 并且把每个对象中的_id拿出来当作key
const testData2: { [key: string]: TestProps } = {
  1: { _id: "1", name: "a" },
  2: { _id: "2", name: "b" }
};

const result2 = objToArr(testData2);
// console.log(result2);
// 将对象类型转换成数组类型
// 0: {_id: '1', name: 'a'}
// 1: {_id: '2', name: 'b'}
// length: 2
// [[Prototype]]: Array(0)
